﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using Hyt.Core.Security;
using Hyt.Data.Ef;
using Hyt.Passport.Models;

namespace Hyt.Passport.Persist
{
    public  class PassportMapping : IEntityMapping
    {
        public void RegisterTo(System.Data.Entity.DbModelBuilder modelBuilder)
        {
            RegisterPrincipal(modelBuilder);
            RegisterAdministrator(modelBuilder);
            RegisterOperationGroup(modelBuilder);
            RegisterOperation(modelBuilder);
            RegisterDepartment(modelBuilder);
            RegisterPosition(modelBuilder);
            RegisterAuthorization(modelBuilder);
        }

        private void RegisterPrincipal(DbModelBuilder modelBuilder)
        {
            //Principal
            var config = modelBuilder.Entity<Principal>();
            config.ToTable("Principal");
            config.HasKey(t => t.Id);
            config.Property(t => t.Id).HasColumnName("Id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
            
        }

        private void RegisterAdministrator(DbModelBuilder modelBuilder)
        {
            //Administrator
            var config = modelBuilder.Entity<Administrator>();
            config.Map(m =>
            {
                //tph
                //m.Requires(t=>t.PrincipalType).HasValue();
                //tpc
                //m.MapInheritedProperties();
                //tpt
                m.ToTable("Administrator");
            });
            //config.HasKey(t => t.Id);
            
            //config.Property(t => t.Id).HasColumnName("Id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
            config.Property(t => t.Name).HasColumnName("Name").HasMaxLength(50).IsRequired();
            config.Property(t => t.UserName).HasColumnName("UserName").HasMaxLength(50).IsRequired();
            config.Property(t => t.Password).HasColumnName("Password").HasMaxLength(50).IsRequired();
            config.Property(t => t.State).HasColumnName("State").IsRequired();
            config.Property(t => t.LastLoginDateTime).HasColumnName("LastLoginDateTime").IsOptional();
            config.Property(t => t.ThisLoginDateTime).HasColumnName("ThisLoginDateTime").IsOptional();
            config.Property(t => t.ThisLoginIp).HasColumnName("ThisLoginIp").HasMaxLength(16).IsOptional();
            config.Property(t => t.LastLoginIp).HasColumnName("LastLoginIp").HasMaxLength(16).IsOptional();
            config.Property(t => t.LoginTimes).HasColumnName("LoginTimes").IsRequired();
            config.Property(t => t.DepartmentId).HasColumnName("DepartmentId").IsOptional();
            config.Property(t => t.PositionId).HasColumnName("PositionId").IsOptional();

            config.HasOptional(t => t.Position).WithMany(t => t.Administrators).HasForeignKey(t => t.PositionId);
            config.HasOptional(t => t.Department).WithMany(t => t.Administrators).HasForeignKey(t => t.DepartmentId);

        }

        private void RegisterOperationGroup(DbModelBuilder modelBuilder)
        {
            //OperationGroup
            var config = modelBuilder.Entity<OperationGroup>();
            config.ToTable("OperationGroup");
            config.HasKey(t => t.Id);

            config.Property(t => t.Id).HasColumnName("Id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
            config.Property(t => t.Name).HasColumnName("Name").HasMaxLength(50).IsRequired();
        }

        private void RegisterOperation(DbModelBuilder modelBuilder)
        {
            //Operation
            var config = modelBuilder.Entity<Operation>();
            config.ToTable("Operation");
            config.HasKey(t => t.Id);

            config.Property(t => t.Id).HasColumnName("Id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
            config.Property(t => t.Code).HasColumnName("Code").IsRequired();
            config.Property(t => t.Name).HasColumnName("Name").HasMaxLength(50).IsRequired();
            config.Property(t => t.Description).HasColumnName("Description").HasMaxLength(255).IsOptional();
            config.Property(t => t.GroupId).HasColumnName("GroupId").IsRequired();

            config.HasRequired(t => t.Group).WithMany(t => t.Operations).HasForeignKey(t => t.GroupId);
        }

        private void RegisterDepartment(DbModelBuilder modelBuilder)
        {
            //Department
            var config = modelBuilder.Entity<Department>();
            //config.ToTable("Department");
            //config.HasKey(t => t.Id);
            config.Map(m =>
            {
                //m.Requires("PrincipalType").HasValue("Department");
                //m.Requires(t => t.PrincipalType).HasValue();//
                //m.MapInheritedProperties();
                m.ToTable("Department");
            });
            //config.Property(t => t.Id).HasColumnName("Id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
            config.Property(t => t.Name).HasColumnName("Name").HasMaxLength(50).IsRequired();
        }

        private void RegisterPosition(DbModelBuilder modelBuilder)
        {
            //Position
            var config = modelBuilder.Entity<Position>();
            //config.ToTable("Position");
            //config.HasKey(t => t.Id);
            config.Map(m =>
            {
                //m.Requires("PrincipalType").HasValue("Position");
                //m.Requires(t => t.PrincipalType).HasValue();//
                //m.MapInheritedProperties();
                m.ToTable("Position");
            });
            //config.Property(t => t.Id).HasColumnName("Id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
            config.Property(t => t.Name).HasColumnName("Name").HasMaxLength(50).IsRequired();
            config.Property(t => t.DepartmentId).HasColumnName("DepartmentId").IsOptional();

            config.HasOptional(t => t.Department).WithMany().HasForeignKey(t => t.DepartmentId);
        }

        private void RegisterAuthorization(DbModelBuilder modelBuilder)
        {
            //Authorization
            var config = modelBuilder.Entity<Authorization>();
            config.ToTable("Authorization");
            config.HasKey(t =>new { t.OperationId,t.PrincipalId});

            config.Property(t => t.OperationId).HasColumnName("OperationId").IsRequired();
            config.Property(t => t.PrincipalId).HasColumnName("PrincipalId").IsRequired();
            config.Property(t => t.State).HasColumnName("State").IsRequired();

            config.HasRequired(t => t.Operation).WithMany().HasForeignKey(t=>t.OperationId);
            config.HasRequired(t => t.Principal).WithMany().HasForeignKey(t=>t.PrincipalId);
        }
    }
}
